!> 终端
module fffc_terminal

    use fffc_utils
    use fffc_kinds, only: wp => fffc_real_kind
    use fffc_terminal_bar, only: progress_bar
    use, intrinsic :: iso_fortran_env, only: stderr => error_unit
    implicit none

    private
    public :: terminal, progress_bar

    character(*), parameter :: colors(*) = [achar(27)//'[31m', &
                                            achar(27)//'[32m', &
                                            achar(27)//'[33m', &
                                            achar(27)//'[34m', &
                                            achar(27)//'[00m', &
                                            achar(27)//'[35m', &
                                            achar(27)//'[36m']

    !> 简单终端
    type terminal
        private
        logical :: use_color = .false.
    contains
        procedure :: init => set_terminal
        procedure :: info => terminal_info
        procedure :: note => terminal_note
        procedure :: warning => terminal_warning
        procedure :: error => terminal_error
        procedure :: success => terminal_success
        procedure :: blue, green, yellow, red, magenta, cyan
    end type terminal

contains

    !> 设置终端输出
    pure subroutine set_terminal(self, use_color)
        class(terminal), intent(inout) :: self
        logical, intent(in), optional :: use_color

        if (present(use_color)) self%use_color = use_color

    end subroutine set_terminal

    !> 信息
    subroutine terminal_info(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg

        print '(a)', self%blue('INFO: '//msg)

    end subroutine terminal_info

    !> 备注
    subroutine terminal_note(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg

        print '(a)', self%cyan('NOTE: '//msg)

    end subroutine terminal_note

    !> 警告
    subroutine terminal_warning(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg

        print '(a)', self%yellow('WARN: '//msg)

    end subroutine terminal_warning

    !> 错误
    subroutine terminal_error(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg

        write (stderr, "(a)") self%red('FAILED: '//msg)
        stop 1

    end subroutine terminal_error

    !> 成功
    subroutine terminal_success(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg

        print '(a)', self%green('OK: '//msg)

    end subroutine terminal_success

    !> 蓝色
    pure function blue(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: blue

        if (self%use_color) then
            blue = colors(4)//msg//colors(5)
        else
            blue = msg
        end if

    end function blue

    !> 绿色
    pure function green(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: green

        if (self%use_color) then
            green = colors(2)//msg//colors(5)
        else
            green = msg
        end if

    end function green

    !> 黄色
    pure function yellow(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: yellow

        if (self%use_color) then
            yellow = colors(3)//msg//colors(5)
        else
            yellow = msg
        end if

    end function yellow

    !> 红色
    pure function red(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: red

        if (self%use_color) then
            red = colors(1)//msg//colors(5)
        else
            red = msg
        end if

    end function red

    !> 品红色
    pure function magenta(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: magenta

        if (self%use_color) then
            magenta = colors(6)//msg//colors(5)
        else
            magenta = msg
        end if

    end function magenta

    !> 青色
    pure function cyan(self, msg)
        class(terminal), intent(in) :: self
        character(*), intent(in) :: msg
        character(:), allocatable :: cyan

        if (self%use_color) then
            cyan = colors(7)//msg//colors(5)
        else
            cyan = msg
        end if

    end function cyan

end module fffc_terminal
